use std::path::Path;

use tokio::{
    fs::{self, File, OpenOptions},
    io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
};

use crate::{APP_DIR, dao::config, utils::{date_util::get_ym_str, file_util, response::R}};

#[tauri::command]
pub fn upload_file(data: Vec<u8>, file_name: String) -> R<String> {
    // 保存路径
    let dic_path;
    match config::get_dic_path_tokio() {
        Some(path) => {
            dic_path = path;
        },
        None => {
            dic_path = APP_DIR.get().unwrap().to_string();
            config::up_dir_config_tokio(dic_path.clone());
        },
    }

    let file_path = Path::new(&((dic_path + "/temp/")))
        .join(get_ym_str())
        .join(Path::new(&file_name));
    let path = file_path.to_str().unwrap().to_string();
    file_util::write_vec_to_file(path.clone(), data);
    return R::data(Some(path));
}



#[tauri::command]
pub async fn read_file(path: String) -> R<String> {
    let file = File::open(path).await;
    match file {
        Ok(file) => {
            let mut buf_reader = BufReader::new(file);
            let mut content = String::new();
            buf_reader.read_to_string(&mut content);
            R::data(Some(content))
        },
        Err(_) => R::fail("打开文件失败！"),
    }

}

#[tauri::command]
pub async fn write_file(path: String, text: String) -> R<bool> {
    let _ = ensure_parent_dir_exists(&path).await;
    let file = if Path::new(&path).exists() {
        // 如果文件存在，打开并覆盖写入
        File::create(path).await
    } else {
        // 文件不存在，自动创建
        OpenOptions::new().write(true).create(true).open(path).await
    };
    match file {
        Ok(file) => {
            let mut writer = BufWriter::new(file);
            writer
                .write_all(text.as_bytes())
                .await
                .unwrap_or_else(|e| log::info!("❌ 写入文件失败{}", e));
            writer
                .flush()
                .await
                .unwrap_or_else(|e| log::info!("❌ 写入文件后关闭文件失败{}", e));
        }
        Err(e) => {
            log::info!("{}", e);
            log::info!("获取文件失败！");
            return R::fail("获取文件失败！");
        }
    }
    R::success()
}

#[tauri::command]
pub async fn del_file(path: String) -> R<bool> {
    fs::remove_file(path)
        .await
        .unwrap_or_else(|e| log::info!("删除文件失败！"));
    R::success()
}

#[tauri::command]
pub async fn copy_file(source_path: String, target_path: String) -> R<bool> {
    println!("📥 拷贝文件：{} -> {}", source_path, target_path);
    let _ = ensure_parent_dir_exists(&target_path).await;
    fs::copy(&source_path, &target_path)
        .await
        .map_err(|e| format!("❌ 复制文件失败: {}", e))
        .unwrap();

    return R::success();
}

#[tauri::command]
pub fn file_exists(path: &str) -> bool {
    let path = Path::new(path);
    match path.try_exists() {
        Ok(bol) => {
            if bol {
                if path.is_file() {
                    if path.metadata().unwrap().len() == 0 {
                        return false;
                    }
                }
                log::info!("存在！");
                return true;
            }
            log::info!("不存在！");
            return false;
        }
        Err(_) => {
            return false;
        }
    }
}

async fn ensure_parent_dir_exists(file_path: &str) -> std::io::Result<()> {
    if let Some(parent) = Path::new(file_path).parent() {
        fs::create_dir_all(parent)
            .await
            .unwrap_or_else(|e| log::info!("❌ 创建目录失败：{}", e));
    }
    Ok(())
}
